package com.back.demo.intercepter;

import com.back.demo.service.BasicService;
import com.back.demo.util.JwtTokenUtil;
import io.swagger.models.HttpMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;

@Component
public class JudgeIntercepter implements HandlerInterceptor {

    @Autowired
    BasicService basicService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    //在将请求发送到控制器controller之前执行操作，若返回true就进入控制器，若返回false就不进入控制器了
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        /*
        问题可能是由于跨域请求导致的。
        当您发送一个前后端分离的请求时，实际上会发送两次请求，第一次是OPTIONS请求，第二次才是GET/POST请求。
        在OPTIONS请求中，不会携带请求头的参数，所以在拦截器中获取请求头为空，自定义的拦截器拦截成功。
        第一次请求不能通过，就不能获取第二次的请求了。
        为了解决这个问题，可以在拦截器中判断：
        如果请求为OPTIONS请求，则返回true，表示可以正常访问，然后就会收到真正的GET/POST请求。
        */
        if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
            System.out.println("OPTIONS请求，放行");
            return true;
        }
        // 解析Authorization请求头中的JWT令牌 Bearer access_token
        String token = request.getHeader("Authorization").substring(7);
        String username = jwtTokenUtil.getUsernameFromToken(token);
        System.out.println("评委拦截器-----开始拦截，在进入控制器之前，拦截器进行拦截该请求，拦截到的token值为:" + token);

        // 拦截器能调用 Spring Boot 管理的类
        ArrayList<Integer> roleIdList = basicService.findRoleIdByUsername(username);
        System.out.println(roleIdList);

        // 有评委角色才可以放行
        return roleIdList.contains(2);
    }

    @Override
    //用于在将响应发送到客户端之前执行操作,就是控制器执行完之后返回数据时执行。
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable
    ModelAndView modelAndView) throws Exception {
        System.out.println("评委拦截器-----控制器执行完毕，返回数据");
    }

    @Override
    //在完成请求和响应后执行操作
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("评委拦截器-----响应结束");
    }

}